<?php
namespace hclient\base;

use hclient\Client;
use hclient\extend\ApiResponse;
use hclient\protocols\http\HttpRequest;

/**
 * 服务站点
 *<B>说明：</B>
 *<pre>
 * 略
 *</pre>
 *
 * @method HttpRequest post(string $url, $data = [],array $options = [])
 * @method array|string postResult(string $url, $data = [],array $options = [])
 * @method HttpRequest get(string $url, $data = [],array $options = [])
 * @method array|string getResult(string $url, $data = [],array $options = [])
 * @method HttpRequest put(string $url, $data = [],array $options = [])
 * @method array|string putResult(string $url, $data = [],array $options = [])
 * @method HttpRequest patch(string $url, $data = [],array $options = [])
 * @method array|string patchResult(string $url, $data = [],array $options = [])
 * @method HttpRequest delete(string $url, $data = [],array $options = [])
 * @method array|string deleteResult(string $url, $data = [],array $options = [])
 * @method HttpRequest head(string $url, $data = [],array $options = [])
 * @method array|string headResult(string $url, $data = [],array $options = [])
 */
class Site
{

    /**
     * 请求客户端
     *<B>说明：</B>
     *<pre>
     *　略
     *</pre>
     * @var Client
     */
    protected $client;

    /**
     * 请求配置
     *<B>说明：</B>
     *<pre>
     *　略
     *</pre>
     * @var array
     */
    protected $options = null;

    public function __construct(array $config = [])
    {
        if (!empty($config)) {
            foreach ($config as $name => $value) {
                $this->$name = $value;
            }
        }
    }

    public function setFormat(string $format):self
    {
        $this->options['format'] = $format;

        return $this;
    }

    public function setTransport(string $transport):self
    {
        $this->options['transport'] = $transport;

        return $this;
    }

    public function setBaseUrl(string $baseUrl):self
    {
        $this->options['baseUrl'] = $baseUrl;

        return $this;
    }

    /**
     * 设置请求配置
     * @param array $requestConfig
     * @return $this
     */
    public function setRequest(array $requestConfig = []):self
    {
        $this->options = array_merge($this->options,$requestConfig);

        return $this;
    }

    /**
     * 设置响应配置
     * @param array $responseConfig
     * @return $this
     */
    public function setResponse(array $responseConfig):self
    {
        if (isset($this->options['response'])) {
            $this->options['response'] = array_merge($this->options['response'],$responseConfig);
        } else {
            $this->options['response'] = $responseConfig;
        }

        return $this;
    }

    /**
     * 创建api 请求对象
     *<B>说明：</B>
     *<pre>
     *　略
     *</pre>
     * @param string $url api 地址
     * @param array|string $data 参数
     * @param array $options request 配置信息
     * @return Request
     */
    public function uri(string $url = '', $data = [],array $options = []):Request
    {
        $siteConf = array_merge($this->options,$options);
        $siteRequest = $this->client->createRequest($siteConf);
        $siteRequest->setUrl($url);

        if (is_array($data)) {
            $siteRequest->setData($data);
        } else {
            $siteRequest->setContent($data);
        }

        return $siteRequest;
    }

    /**
     * 发送api 请求
     *<B>说明：</B>
     *<pre>
     *　略
     *</pre>
     * @param string $url api 地址
     * @param array|string $data 参数
     * @param array $options request 配置信息
     * @return mixed
     */
    public function uriResult(string $url = '', $data = [],array $options = [])
    {
        return $this->uri($url,$data,$options)->send()->getData();
    }

    /**
     * 发送api 请求
     *<B>说明：</B>
     *<pre>
     *　略
     *</pre>
     * @param string $url api 地址
     * @param array $data 参数
     * @param array $options request 配置信息
     * @return mixed
     */
    public function api(string $url = '', $data = [],array $options = []):ApiResponse
    {
        return $this->uri($url,$data,$options)->send();
    }

    /**
     * 创建Request 快捷方法
     *<B>说明：</B>
     *<pre>
     *　不支持api
     *</pre>
     * @param string $method 方法名
     * @param string $url 目标地址
     * @param array|string $data request date request content
     * @param array $options request 配置
     * @return Request request 实例
     */
    protected function createRequestShortcut(string $method,string $url, array $data = null,array $options = []):Request
    {
        $request = call_user_func_array([$this->client,$method],[$url,$data,array_merge($this->options,$options)]);

        return $request;
    }

    /**
     * 调用默认存储方法
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param string $method 方法名称
     * @param array $parameters 参数
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        if (substr($method,-6) == 'Result') {
            $methodName = substr($method,0,-6);
            $request = $this->createRequestShortcut($methodName,...$parameters);
            return $request->send()->getData();
        } else {
            return $this->createRequestShortcut($method,...$parameters);
        }
    }
}
